package com.hsxc.cdz.controller.appController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hsxc.cdz.base.bean.MyUser;
import com.hsxc.cdz.base.bean.Reserv;
import com.hsxc.cdz.base.util.CommonUtils;
import com.hsxc.cdz.base.util.Constants;
import com.hsxc.cdz.base.util.TimeFormatter;
import com.hsxc.cdz.biz.reserve.ReservManager;
import com.hsxc.cdz.mgmt.GlobalManager;
import com.hsxc.cdz.mgmt.mobileMessage.MobileMessage;
import com.hsxc.cdz.monitor.FSM.CachePile;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 预约
 *
 * @author llw
 */
@Controller("appReserve")
@RequestMapping("/app")
public class ReserveController {

    @Autowired
    private ReservManager reservManager;

    Logger logger = LoggerFactory.getLogger(ReserveController.class);

    @RequestMapping(value = "/reserve", method = RequestMethod.POST)
    @ResponseBody
    public Object Reserve(@RequestBody String json) {
        logger.info("START RESERV POST");
        JSONObject result = new JSONObject();
        result.put("success", true);
        JSONObject param = JSONObject.fromObject(json);
        Subject subject = SecurityUtils.getSubject();
        if (subject == null || subject.getPrincipal() == null) {
            result.put("added", false);
            result.put("errcode", MyUser.NO_LOGIN);
            result.put("message", "当前用户没有登录");
            return result;
        }
        String trueTel = subject.getPrincipal().toString();
        String cardNo = trueTel;// 此处为卡号，因为必须为20位数字
        String stationNo = param.getString("stationNo");
        int duration = 2 * 60;//  默认预约两个小时
        int port = 0;
        String startTime = null;
        String endTime = null;
        if (param.has("duration")) {
            duration = param.getInt("duration");
        }
        if (param.has("port")) {
            port = param.getInt("port");
        }
        if (param.has("startTime")) {
            startTime = param.getString("startTime");
        }
        if (param.has("endTime")) {
            endTime = param.getString("endTime");
        }
        if (trueTel == null || stationNo == null || trueTel == "" || stationNo == "") {
            result.put("errcode", 1);
            result.put("message", "参数为空");
            return result;
        }
        if (startTime != null && endTime != null) {
            Calendar calendarStart = TimeFormatter.dateFromString(startTime);
            Calendar calendarEnd = TimeFormatter.dateFromString(endTime);
            duration = (int) (calendarEnd.getTimeInMillis() - calendarStart.getTimeInMillis()) / 1000 / 60;
        }
        while (cardNo.length() < 20) {
            cardNo += "0";
        }
        logger.info("GET IDLE CACHEPILE");
        // 从内存中查找是否有可以预约的电桩,即查找空闲状态桩
        List<CachePile> idleCachePiles = GlobalManager.pileManager.getIdleCachePileByStationNo(stationNo);

        if (idleCachePiles == null || idleCachePiles.size() == 0) {
            result.put("errcode", 2);
            result.put("message", "该电站没有可以预约的电桩");
            return result;
        }
        // 随机分配一个电桩进行预约
        int randomInt = new Random().nextInt(idleCachePiles.size());
        CachePile cachePile = idleCachePiles.get(randomInt);
        logger.info("CACHEPILE PILE STATUS" + cachePile.getStatus());
        // 设置预约属性
        Reserv reserv = new Reserv();
        reserv.setResNo(CommonUtils.getTID());
        reserv.setPileNo(cachePile.getAddress());
        reserv.setReservCreateTime(TimeFormatter.toTimeYear());
        reserv.setCancelled(false);
        // 获取开始时间并得到结束时间
        reserv.setUserNo(cardNo);
        reserv.setStationNo(stationNo);
        reserv.setOperatorNo(cachePile.getOperator());
        reserv.setState(Reserv.RESERV_STATE_ON);
        //交流桩，开始时间及结束时间均没有用
        reserv.setReservStartTime(startTime);
        reserv.setReservStopTime(endTime);
        //直流桩才需要参数duration
        reserv.setDuration(duration);

        //reserv.setCachePile(cachePile);
        if (GlobalManager.cacheReservManager.addReserv(reserv) != 0) {
            result.put("errcode", 3);
            result.put("message", "缓存预约添加失败");
            return result;
        }
        if (reservManager.insertReserv(reserv) != 1) {
            result.put("errcode", 4);
            result.put("message", "数据库插入预约失败");
            return result;
        }
        // 发送预约指令
        final int portFinal = port;
        if (cachePile.reserve(port, cardNo, duration) == 0) {
            // 提醒及时充电
            Timer timer1 = new Timer();
            timer1.schedule(new TimerTask() {
                public void run() {
                    JSONArray params = new JSONArray();
                    params.add("30分钟");
                    params.add(GlobalManager.stationManager.getStationAddressByStationNo(reserv.getStationNo()));
                    params.add(reserv.getPileNo());
                    MobileMessage.sendMsgReserv(Constants.TEMPLATE_ID_INFO_RESERV, trueTel, params);
                }
            }, 0 * 60 * 1000);// cachePile.duration - 30 *
            // 60,10*60);//第二个参数为开始时间，第三个参数为开始后按十分钟间隔发送
            reserv.setTimerTask(new TimerTask() {
                @Override
                public void run() {
                    Calendar calendar = TimeFormatter.dateFromString(reserv.getReservCreateTime());
                    //一个小时后自动取消预约
                    calendar.add(Calendar.HOUR_OF_DAY, 1);
                    Calendar nowCalendar = Calendar.getInstance();
                    if (nowCalendar.after(calendar) && reserv.getState() != Reserv.RESERV_STATE_FINISH) {
                        cachePile.reservationCancel(reserv.getChargePort(), reserv.getUserNo());
//                        GlobalManager.cacheReservManager.removeReserv(reserv.getResNo());
//                        if (reserv.getState() != Reserv.RESERV_STATE_FINISH)
//                            GlobalManager.reservManager.updateReserv(reserv.getResNo(), true, Reserv.RESERV_STATE_CANCELL);

                    }
                }
            });


            GlobalManager.cacheReservManager.addReserv(reserv);
            //一小时后执行一次
            GlobalManager.timer.schedule(reserv.getTimerTask(), 1 * 60 * 60 * 1000);//一小时后将没有完成的预约给取消
            //GlobalManager.timer.scheduleAtFixedRate(reserv.getTimerTask(), 55 * 60 * 1000, 1 * 60 * 60 * 1000);
            result.put("errcode", 0);
            ObjectMapper mapper = new ObjectMapper();
            String res = null;
            try {
                res = mapper.writeValueAsString(reserv);
                logger.info(res);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                result.put("errcode", 2);
                result.put("message", "您没有预约记录");
                logger.info("json 序列化异常");
                return result;
            }
            result.put("data", res);
            return result;
        } else {
            result.put("errcode", 5);
            result.put("message", "发送预约指令失败");
            return result;
        }
    }

    // 获取预约记录信息
    @RequestMapping(value = "/reserve", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Object getReserv() {
        logger.info("START TO REQUEST RESERV GET");
        JSONObject result = new JSONObject();
        result.put("success", true);
        List<Reserv> reservs = null;
        Subject subject = SecurityUtils.getSubject();
        if (subject == null || subject.getPrincipal() == null) {
            result.put("added", false);
            result.put("errcode", MyUser.NO_LOGIN);
            result.put("message", "当前用户没有登录");
            return result;
        }
        String tel = subject.getPrincipal().toString();
        if (tel == null) {
            result.put("added", false);
            result.put("errcode", 1);
            result.put("message", "用户信息输入有误");
            return result;
        }
        while (tel.length() < 20) {
            tel += "0";
        }
        reservs = reservManager.selReserv(tel);
        if (reservs == null || reservs.size() == 0) {
            logger.info("reserv is empty");
            result.put("errcode", 2);
            result.put("message", "没有预约记录");
            return result;
        }
        logger.info("return reservs");
        result.put("errcode", 0);
        ObjectMapper mapper = new ObjectMapper();
        String re = null;
        try {
            re = mapper.writeValueAsString(reservs);
            logger.info(re);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            result.put("errcode", 2);
            result.put("message", "您没有预约记录");
            logger.info("json 序列化异常");
            return result;
        }
        result.put("data", re);
        return result;
    }

    /**
     * 取消预约
     *
     * @param resNo
     * @return
     */
    @RequestMapping(value = "/reserve/{resNo}", method = RequestMethod.DELETE)
    @ResponseBody
    public Object delReserv(@PathVariable("resNo") String resNo) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        Subject subject = SecurityUtils.getSubject();
        if (subject == null || subject.getPrincipal() == null) {
            result.put("added", false);
            result.put("errcode", MyUser.NO_LOGIN);
            result.put("message", "当前用户没有登录");
            return result;
        }
        String tel = subject.getPrincipal().toString();
        String trueTel = tel;
        while (tel.length() < 20) {
            tel += "0";
        }
        if (resNo == null || resNo == "") {
            result.put("success", false);
            result.put("errcode", 1);
            result.put("message", "参数错误");
            return result;
        }
        Reserv reserv = reservManager.selReservByNo(resNo);
        if (reserv == null) {
            result.put("errcode", 2);
            result.put("message", "未找到该预约");
            return result;
        }

        CachePile cachePile = GlobalManager.pileManager.getPile(reserv.getPileNo());
        if (cachePile == null) {
            result.put("errcode", 3);
            result.put("message", "解锁桩时未找到该桩");
            return result;
        }
        logger.info("--DELETE RESERV pile status--" + cachePile.getStatus());
        if (cachePile.reservationCancel(0, tel) == 1) {
            result.put("errcode", 4);
            result.put("message", "取消预约失败");
            return result;
        }
        result.put("errcode", 0);
        result.put("data", "取消成功");
        return result;
    }
}
